// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#include "mk_header.h"
#include "mk_skinning.h"
#include "mk_error.h"
#include "mk_skeleton.h"
#include "mk_math.h"

namespace MK3DE
{
	CSkinning::CSkinning()
	{

	}

	CSkinning::~CSkinning()
	{

	}

	BOOL CSkinning::BlendVertex(CMesh::Position* positions, CMesh::Normal* normals, 
		CMesh::Influence* skins, CSkeleton* pSkeleton, CMesh::Position* pPosition, 
		CMesh::Normal* pNormal, int size)
	{
		for (int i = 0; i < size; ++i)
		{
			D3DXVECTOR3& pos = positions[i];
			D3DXVECTOR3& nor = normals[i];
			CMesh::Influence& influence = skins[i];
			D3DXVECTOR3 position(0, 0, 0);
			D3DXVECTOR3 normal(0, 0, 0);
			for (DWORD j = 0; j < 4; ++j)
			{
				if (influence.boneIdx[j] == 0xff)
					break;

				int boneIdx = influence.boneIdx[j];
				float weight = influence.weight[j];

				CBone* pBone = pSkeleton->GetBone(boneIdx);
				assert(pBone);
				if (!pBone)
					return FALSE;

				D3DXMATRIX mat = pBone->GetLocalTransformFromBase();
				D3DXVECTOR3 p, n;
				D3DXVec3TransformCoord(&p, &pos, &mat);
				D3DXVec3TransformNormal(&n, &nor, &mat);

				position += p * weight;
				normal += n * weight;
			}

			pPosition[i] = position;
			pNormal[i] = normal;
		}

		return TRUE;
	}
}